#ifndef CLEAN_H_
#define CLEAN_H_

#include "Spectrum.h"

#include <vector>
#include <complex>
#include <limits>

namespace spectClean {

/**
 * @class Clean
 *
 * @brief
 *
 * @details
 */

class Clean
{
    public:
        Clean();
        ~Clean();

        typedef std::complex<double> Complex;

    public:
        void simpleClean(const Spectrum & psf, Spectrum & cleanComponents,
                Spectrum & residual, const unsigned num_iterations,
                const double gain);

        unsigned findMaxIndex(const Complex * data, const unsigned n);

        unsigned findMaxIndex2(const Complex * data,
                const unsigned index_start, const unsigned index_end,
                const double old_max = -std::numeric_limits<double>::max());

        void make_clean_spectrum(const Spectrum & clean_components,
                Spectrum & clean_spectrum);


//        /// Construct the clean beam.
//        void makeCleanBeam(SpectrumData * window, SpectrumData * cleanBeam);
//
//        /// Setup the residual, components and clean spectra ready for the clean step
//        void initClean(SpectrumData * dirty, SpectrumData * residual,
//                SpectrumData * components, SpectrumData * clean,
//                SpectrumData * cleanResidual);
//
//        /// Clean the dirty spectrum
//        void cleanSpectrum(unsigned loops, double gain, SpectrumData * window,
//                SpectrumData * residual, SpectrumData * components);
//
//        /// Construct the clean spectrum
//        void makeCleanSpect(SpectrumData *clean, SpectrumData *cleanResiual,
//                SpectrumData * components, SpectrumData * residual,
//                SpectrumData * cleanBeam);

    private:
//        /// Find the full width half max. of the peak in the window function
//        void _returnFwhmWindow(SpectrumData * window, double * fwhm,
//                unsigned * iFwhm);
//
//        /// Find the index of the max. point in a vector for the specified
//        /// index range
//        int _findMaxIndex(vector<Complex> values, unsigned int iStart,
//                unsigned int iEnd);
//
//        /// Find the index of max value in a vector.
//        /// (skipping a max at the specified bad index)
//        int _findMaxSafeIndex(vector<Complex> values, unsigned iStart,
//                unsigned iEnd, unsigned iBad);

    private:
//        typedef struct
//        {
//            vector<double> peakAmp;
//            vector<double> peakFreq;
//            vector<double> extraComponentAmp;
//            vector<double> totalComponentAmp;
//        } _CleanHistory;
//
//        /// clean component hit list
//        _CleanHistory _cleanHistory;
};

} // namespace spectClean
#endif // CLEAN_H_
